/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package libs.game.sokoban;

import libs.game.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;



/**
 *
 * @author      Jan Papousek
 * @version     2009-02-22
 */
public class SokobanGame implements Game{

    private SokobanGamePlan gamePlan;

    private Path personPath;

    private Map<Coordinates,Path> goalPaths = new HashMap<Coordinates, Path>();

    private Map<Coordinates,Path> boxPaths = new HashMap<Coordinates, Path>();

    /**
     *          It creates new sokoban game.
     *
     * @param   fileName    Source file name.
     * @throws  IOException if there is a problem to load data from file.
     */
    public SokobanGame(String fileName) throws IOException {
        this.gamePlan = SokobanGamePlanFactory.createFromFile(fileName);
        computePaths();
    }

    /**
     *          It creates a new sokoban game.
     *
     * @param   plan    Sokoban game plan.
     */
    public SokobanGame(SokobanGamePlan plan) {
        if (plan == null) {
            throw new NullPointerException("Argument 'plan' is null.");
        }
        gamePlan = plan;
        computePaths();
    }

    public void computePaths() {
        personPath = new PersonPath(gamePlan);
        for (Coordinates box : gamePlan.getBoxes()) {
            boxPaths.put(box, new BoxPath(gamePlan, box));
        }
        for(Coordinates goal : gamePlan.getGoals()) {
            goalPaths.put(goal, new GoalPath(gamePlan, goal, boxPaths));
        }

    }

    @Override
    public GamePlan getGamePlan() {
        return this.gamePlan;
    }

    public Path getPersonPath() {
        return personPath;
    }

    public Map<Coordinates,Path> getGoalPaths() {
        return goalPaths;
    }

    public Map<Coordinates,Path> getBoxPaths() {
        return boxPaths;
    }

    @Override
    public boolean isSolved() {
        return new SokobanSolution(gamePlan).isSolved();
    }

    @Override
    public boolean isLocked() {
        return new SokobanSimpleDeadlock(gamePlan, goalPaths).isLocked();
    }
}
